using Engine;
using Engine.Graphics;
using System.Collections.Generic;
using System.Globalization;

namespace Game
{
	public class FireworksBlock : Block
	{
		public enum Shape
		{
			SmallBurst,
			LargeBurst,
			Circle,
			Disc,
			Ball,
			ShortTrails,
			LongTrails,
			FlatTrails
		}

		public static int Index = 215;

		public BlockMesh[] m_headBlockMeshes = new BlockMesh[64];

		public BlockMesh[] m_bodyBlockMeshes = new BlockMesh[2];

		public BlockMesh[] m_finsBlockMeshes = new BlockMesh[2];

		public static readonly string[] HeadNames = new string[8]
		{
			"HeadConeSmall",
			"HeadConeLarge",
			"HeadCylinderSmall",
			"HeadCylinderLarge",
			"HeadSphere",
			"HeadDiamondSmall",
			"HeadDiamondLarge",
			"HeadCylinderFlat"
		};

		public static readonly Color[] FireworksColors = new Color[8]
		{
			new(255, 255, 255),
			new(85, 255, 255),
			new(255, 85, 85),
			new(85, 85, 255),
			new(255, 255, 85),
			new(85, 255, 85),
			new(255, 170, 0),
			new(255, 85, 255)
		};

		public override void Initialize()
		{
			Model model = ContentManager.Get<Model>("Models/Fireworks");
			Matrix boneAbsoluteTransform = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Body").ParentBone);
			Matrix boneAbsoluteTransform2 = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Fins").ParentBone);
			for (int i = 0; i < 64; i++)
			{
				int num = i / 8;
				int num2 = i % 8;
				Color color = FireworksColors[num2];
				color *= 0.75f;
				color.A = byte.MaxValue;
				Matrix boneAbsoluteTransform3 = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh(HeadNames[num]).ParentBone);
				m_headBlockMeshes[i] = new BlockMesh();
				m_headBlockMeshes[i].AppendModelMeshPart(model.FindMesh(HeadNames[num]).MeshParts[0], boneAbsoluteTransform3 * Matrix.CreateTranslation(0f, -0.25f, 0f), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, color);
			}
			for (int j = 0; j < 2; j++)
			{
				float num3 = 0.5f + (j * 0.5f);
				var m = Matrix.CreateScale(new Vector3(num3, 1f, num3));
				m_bodyBlockMeshes[j] = new BlockMesh();
				m_bodyBlockMeshes[j].AppendModelMeshPart(model.FindMesh("Body").MeshParts[0], boneAbsoluteTransform * m * Matrix.CreateTranslation(0f, -0.25f, 0f), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
			}
			for (int k = 0; k < 2; k++)
			{
				m_finsBlockMeshes[k] = new BlockMesh();
				m_finsBlockMeshes[k].AppendModelMeshPart(model.FindMesh("Fins").MeshParts[0], boneAbsoluteTransform2 * Matrix.CreateTranslation(0f, -0.25f, 0f), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, (k == 0) ? Color.White : new Color(224, 0, 0));
			}
			base.Initialize();
		}

		public override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
		{
		}

		public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
		{
			int data = Terrain.ExtractData(value);
			int color2 = GetColor(data);
			Shape shape = GetShape(data);
			int altitude = GetAltitude(data);
			bool flickering = GetFlickering(data);
			BlocksManager.DrawMeshBlock(primitivesRenderer, m_headBlockMeshes[((int)shape * 8) + color2], color, 2f * size, ref matrix, environmentData);
			BlocksManager.DrawMeshBlock(primitivesRenderer, m_bodyBlockMeshes[altitude], color, 2f * size, ref matrix, environmentData);
			BlocksManager.DrawMeshBlock(primitivesRenderer, m_finsBlockMeshes[flickering ? 1 : 0], color, 2f * size, ref matrix, environmentData);
		}

		public override string GetDisplayName(SubsystemTerrain subsystemTerrain, int value)
		{
			int data = Terrain.ExtractData(value);
			int color = GetColor(data);
			Shape shape = GetShape(data);
			int altitude = GetAltitude(data);
			bool flickering = GetFlickering(data);
			return string.Format(LanguageControl.GetFireworks("Other", "1"), LanguageControl.GetFireworks("FireworksColorDisplayNames", color.ToString()), flickering ? LanguageControl.GetFireworks("Other", "2") : null, LanguageControl.GetFireworks("ShapeDisplayNames", ((int)shape).ToString()), (altitude == 0) ? LanguageControl.GetFireworks("Other", "3") : LanguageControl.GetFireworks("Other", "4"));
		}

		public override IEnumerable<int> GetCreativeValues()
		{
			int color = 0;
			while (color < 8)
			{
				int num;
				for (int altitude = 0; altitude < 2; altitude = num)
				{
					for (int flickering = 0; flickering < 2; flickering = num)
					{
						for (int shape = 0; shape < 8; shape = num)
						{
							yield return Terrain.MakeBlockValue(215, 0, SetColor(SetAltitude(SetShape(SetFlickering(0, flickering != 0), (Shape)shape), altitude), color));
							num = shape + 1;
						}
						num = flickering + 1;
					}
					num = altitude + 1;
				}
				num = color + 1;
				color = num;
			}
		}

		public override IEnumerable<CraftingRecipe> GetProceduralCraftingRecipes()
		{
			int shape = 0;
			while (shape < 8)
			{
				int num;
				for (int altitude = 0; altitude < 2; altitude = num)
				{
					for (int flickering = 0; flickering < 2; flickering = num)
					{
						for (int color = 0; color < 8; color = num)
						{
							var craftingRecipe = new CraftingRecipe
							{
								ResultCount = 20,
								ResultValue = Terrain.MakeBlockValue(215, 0, SetColor(SetAltitude(SetShape(SetFlickering(0, flickering != 0), (Shape)shape), altitude), color)),
								RemainsCount = 1,
								RemainsValue = Terrain.MakeBlockValue(90),
								RequiredHeatLevel = 0f,
								Description = "ÖÆ×÷ÑÌ»¨"
							};
							if (shape == 0)
							{
								craftingRecipe.Ingredients[0] = null;
								craftingRecipe.Ingredients[1] = "sulphurchunk";
								craftingRecipe.Ingredients[2] = null;
							}
							if (shape == 1)
							{
								craftingRecipe.Ingredients[0] = "sulphurchunk";
								craftingRecipe.Ingredients[1] = "coalchunk";
								craftingRecipe.Ingredients[2] = "sulphurchunk";
							}
							if (shape == 2)
							{
								craftingRecipe.Ingredients[0] = "sulphurchunk";
								craftingRecipe.Ingredients[1] = null;
								craftingRecipe.Ingredients[2] = "sulphurchunk";
							}
							if (shape == 3)
							{
								craftingRecipe.Ingredients[0] = "sulphurchunk";
								craftingRecipe.Ingredients[1] = "sulphurchunk";
								craftingRecipe.Ingredients[2] = "sulphurchunk";
							}
							if (shape == 4)
							{
								craftingRecipe.Ingredients[0] = "coalchunk";
								craftingRecipe.Ingredients[1] = "coalchunk";
								craftingRecipe.Ingredients[2] = "coalchunk";
							}
							if (shape == 5)
							{
								craftingRecipe.Ingredients[0] = null;
								craftingRecipe.Ingredients[1] = "saltpeterchunk";
								craftingRecipe.Ingredients[2] = null;
							}
							if (shape == 6)
							{
								craftingRecipe.Ingredients[0] = "sulphurchunk";
								craftingRecipe.Ingredients[1] = "saltpeterchunk";
								craftingRecipe.Ingredients[2] = "sulphurchunk";
							}
							if (shape == 7)
							{
								craftingRecipe.Ingredients[0] = "coalchunk";
								craftingRecipe.Ingredients[1] = "saltpeterchunk";
								craftingRecipe.Ingredients[2] = "coalchunk";
							}
							if (flickering == 0)
							{
								craftingRecipe.Ingredients[3] = "canvas";
								craftingRecipe.Ingredients[5] = "canvas";
							}
							if (flickering == 1)
							{
								craftingRecipe.Ingredients[3] = "gunpowder";
								craftingRecipe.Ingredients[5] = "gunpowder";
							}
							if (altitude == 0)
							{
								craftingRecipe.Ingredients[6] = "gunpowder";
								craftingRecipe.Ingredients[7] = null;
								craftingRecipe.Ingredients[8] = "gunpowder";
							}
							if (altitude == 1)
							{
								craftingRecipe.Ingredients[6] = "gunpowder";
								craftingRecipe.Ingredients[7] = "gunpowder";
								craftingRecipe.Ingredients[8] = "gunpowder";
							}
							craftingRecipe.Ingredients[4] = "paintbucket:" + ((color != 7) ? color : 10).ToString(CultureInfo.InvariantCulture);
							yield return craftingRecipe;
							num = color + 1;
						}
						num = flickering + 1;
					}
					num = altitude + 1;
				}
				num = shape + 1;
				shape = num;
			}
		}

		public static Shape GetShape(int data)
		{
			return (Shape)(data & 7);
		}

		public static int SetShape(int data, Shape shape)
		{
			return (data & -8) | (int)(shape & Shape.FlatTrails);
		}

		public static int GetAltitude(int data)
		{
			return (data >> 3) & 1;
		}

		public static int SetAltitude(int data, int altitude)
		{
			return (data & -9) | ((altitude & 1) << 3);
		}

		public static bool GetFlickering(int data)
		{
			return ((data >> 4) & 1) != 0;
		}

		public static int SetFlickering(int data, bool flickering)
		{
			return (data & -17) | ((flickering ? 1 : 0) << 4);
		}

		public static int GetColor(int data)
		{
			return (data >> 5) & 7;
		}

		public static int SetColor(int data, int color)
		{
			return (data & -225) | ((color & 7) << 5);
		}
	}
}
